﻿using System;
using System.Threading;

namespace CS.Scheduling
{
    /// <summary>
    /// 简单任务抽象
    /// </summary>
    public abstract class Mission : IDisposable
    {
        private Timer _timer;

        private int _duteTime;//延迟时间量（以毫秒为单位）

        private int _period; //时间间隔（以毫秒为单位）

        protected Mission()
        {
            IsDisposed = false;
        }

        private void Run(object state)
        {
            ExecuteException = null;//清除上次可能的异常
            Pause();
            try
            {
                Execute();
            }
            catch (Exception ex)
            {
                ExecuteException = ex;
            }
            finally
            {
                Resume();
            }
        }
        /// <summary>
        /// 任务恢复
        /// </summary>
        public void Resume()
        {
            if (_timer != null && !IsDisposed)
            {
                _timer.Change(_duteTime, _period);
            }
        }
        /// <summary>
        ///  任务暂停
        /// </summary>
        public void Pause()
        {
            if (_timer != null && !IsDisposed)
            {
                _timer.Change(Timeout.Infinite, Timeout.Infinite);
            }
        }
        /// <summary>
        /// 任务完成
        /// </summary>
        public void Finish()
        {
            Dispose();
        }
        /// <summary>
        /// 是否已释放
        /// </summary>
        public bool IsDisposed { get; private set; }

        public void Dispose()
        {
            lock (this)
            {
                if (!IsDisposed) IsDisposed = true;
                if (_timer == null) return;
                _timer.Dispose();
                _timer = null;
            }
        }

        /// <summary>
        /// 立即开始任务
        /// </summary>
        /// <param name="period">时间间隔（以毫秒为单位）</param>
        public void Start(int period)
        {
            Start(1,period);
        }

        /// <summary>
        /// 任务开始
        /// </summary>
        /// <param name="dueTime">延迟时间量（以毫秒为单位）</param>
        /// <param name="period">时间间隔（以毫秒为单位）</param>
        public void Start(int dueTime, int period)
        {
            lock (this)
            {
                if (IsDisposed) return;
                _duteTime = dueTime.ToInt(1, 1, int.MaxValue); //如果为0时会有问题
                _period = period.ToInt(1,1,int.MaxValue);
                _timer = new Timer(Run, null, dueTime, period);
            }
        }

        /// <summary>
        /// 执行
        /// <remarks>由子类实现的调用方法</remarks>
        /// </summary>
        protected abstract void Execute();
        /// <summary>
        /// 执行Execute中抛出的异常
        /// </summary>
        public Exception ExecuteException { get; private set; }

    }
}